package com.itheima;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;

import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.LinkedList;
import java.util.Queue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

public class RecursiveMarkdownImageUploader {

    private static final String ENDPOINT = "oss-cn-beijing.aliyuncs.com";
    private static final String ACCESS_KEY_ID = "LTAI5t5mcMQ1ddSAkHnpWdqN";
    private static final String ACCESS_KEY_SECRET = "YwEi6ZAnvQKLMO8o7SRFrvxYgaqfwt";
    private static final String BUCKET_NAME = "schaeferpic";
    private static final Path ROOT_DIRECTORY_PATH = Paths.get("/Users/macbook14/Desktop/讲义");
    private static final String LOG_FILE_PATH = "/Users/macbook14/Desktop/error_log.txt";

    public static void main(String[] args) {
        Queue<String> errorQueue = new LinkedList<>();
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        try {
            processDirectory(ROOT_DIRECTORY_PATH, ossClient, errorQueue);
            System.out.println("所有Markdown文件中的图片已更新为OSS URL。");
        } finally {
            ossClient.shutdown();
            writeErrorsToFile(errorQueue);
        }
    }

    private static void processDirectory(Path directory, OSS ossClient, Queue<String> errorQueue) {
        try (Stream<Path> paths = Files.walk(directory)) {
            paths.filter(Files::isRegularFile)
                    .filter(path -> path.toString().endsWith(".md"))
                    .forEach(path -> updateMarkdownFile(path, ossClient, errorQueue));
        } catch (IOException e) {
            System.err.println("Error walking through directory: " + directory);
            e.printStackTrace();
        }
    }

    private static void updateMarkdownFile(Path markdownFilePath, OSS ossClient, Queue<String> errorQueue) {
        try {
            String content = new String(Files.readAllBytes(markdownFilePath), StandardCharsets.UTF_8);
            // Regular expression for Markdown image syntax
            Pattern markdownPattern = Pattern.compile(
                    "!\\[.*?\\]\\((images[\\\\/][^\\)]+?\\.(jpg|png|gif|webp|bmp|jpeg|svg|tiff))\\)"
            );
            // Regular expression for HTML <img> tags
            Pattern htmlImgPattern = Pattern.compile(
                    "<img\\s+[^>]*src=\"([^\"]+?)\"[^>]*>"

            );

            Matcher matcher = markdownPattern.matcher(content);
            content = updateImagesInContent(matcher, content, ossClient, markdownFilePath, errorQueue);

            matcher = htmlImgPattern.matcher(content);
            content = updateImagesInContent(matcher, content, ossClient, markdownFilePath, errorQueue);

            Files.write(markdownFilePath, content.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            System.err.println("Error updating Markdown file: " + markdownFilePath);
            e.printStackTrace();
        }
    }

    private static String updateImagesInContent(Matcher matcher, String content, OSS ossClient, Path markdownFilePath, Queue<String> errorQueue) {
        while (matcher.find()) {
            String imagePath = matcher.group(1);
            System.out.println("Processing image path: " + imagePath); // Log for debugging

            if (imagePath.startsWith("http://") || imagePath.startsWith("https://")) {
                continue; // Skip already absolute URLs
            }

            imagePath = normalizePath(imagePath);
            imagePath = decodePath(imagePath);

            Path resolvedPath = markdownFilePath.getParent().resolve(imagePath).normalize();
            if (!Files.exists(resolvedPath)) {
                resolvedPath = tryCommonDirectories(markdownFilePath, imagePath);
                if (resolvedPath == null || !Files.exists(resolvedPath)) {
                    errorQueue.offer("File not found: " + resolvedPath);
                    continue;
                }
            }

            File file = resolvedPath.toFile();
            String ossImageUrl = uploadImageToOSS(ossClient, file, markdownFilePath.getFileName().toString().replace(".md", ""));
            content = content.replaceAll(Pattern.quote(matcher.group(0)), matcher.group(0).replace(matcher.group(1), ossImageUrl));
        }
        return content;
    }


    private static Path tryCommonDirectories(Path markdownFilePath, String imagePath) {
        // Common directory names where images might be stored
        String[] commonDirs = {"img", "imgs", "assets"};

        // First try the exact path or modified path based on common directory names
        for (String dir : commonDirs) {
            Path resolvedPath = markdownFilePath.getParent().resolve(dir + "/" + new File(imagePath).getName()).normalize();
            System.out.println("Trying path: " + resolvedPath);  // Log for debugging
            if (Files.exists(resolvedPath)) {
                return resolvedPath;
            }
        }

        // If not found, try to climb up to the parent directory and search within common directories
        Path parentPath = markdownFilePath.getParent();
        while (parentPath != null && parentPath.startsWith(ROOT_DIRECTORY_PATH)) {
            for (String dir : commonDirs) {
                Path resolvedPath = parentPath.resolve(dir).resolve(new File(imagePath).getName()).normalize();
                System.out.println("Trying parent path: " + resolvedPath);  // Additional log for debugging
                if (Files.exists(resolvedPath)) {
                    return resolvedPath;
                }
            }
            parentPath = parentPath.getParent();
        }
        return null;
    }



    private static String normalizePath(String path) {
        return path.replace('\\', '/');
    }

    private static String decodePath(String path) {
        try {
            return URLDecoder.decode(path, StandardCharsets.UTF_8.name());
        } catch (UnsupportedEncodingException e) {
            System.err.println("Error decoding path: " + path);
            return path;
        }
    }
    private static String uploadImageToOSS(OSS ossClient, File file, String directoryName) {
        String objectName = directoryName + "/" + file.getName();
        if (objectName.startsWith("/")) {
            objectName = objectName.substring(1);
        }
        ossClient.putObject(new PutObjectRequest(BUCKET_NAME, objectName, file));
        String ossUrl = "https://" + BUCKET_NAME + "." + ENDPOINT + "/" + objectName;
        System.out.println("Uploaded to OSS and updated URL: " + ossUrl); // Log the new URL for checking
        return ossUrl;
    }

    private static void writeErrorsToFile(Queue<String> errorQueue) {
        try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(LOG_FILE_PATH), StandardCharsets.UTF_8))) {
            writer.println("Errors:");
            while (!errorQueue.isEmpty()) {
                String error = errorQueue.poll();
                writer.println(error);
                System.out.println("Logged error: " + error); // Log errors for debugging
            }
        } catch (IOException e) {
            System.err.println("Error writing to error log file: " + LOG_FILE_PATH);
            e.printStackTrace();
        }
    }
}

